package app

import (
	"a-admin/web/resp"
	"a-app/domain/entity"
	"a-app/domain/pojo"
	"a-app/service"
	"a-common/config"
	"a-common/constant"
	"a-common/myerr"
	"a-common/utils/captcha"
	"a-common/utils/email"
	"a-common/utils/ipaddr"
	sys "a-system/service"
	"sync"

	"github.com/gofiber/fiber/v2"
	"github.com/mssola/user_agent"
)

var (
	appApiControllerTemp *AppApiController
	appLoginService      = service.NewAppLoginService()
	appApiControllerOnce sync.Once

	captchaUtils = captcha.New()
	emailUtils   = email.New()
)

type AppApiController struct{}

func NewAppApiController() *AppApiController {
	appApiControllerOnce.Do(func() {
		appApiControllerTemp = &AppApiController{}
	})
	return appApiControllerTemp
}

// Login 用户登陆
func (m *AppApiController) Login(c *fiber.Ctx) error {
	var ip string
	var userName string
	var err error
	var token string
	defer func() {
		// 获取 User-Agent
		userAgentString := c.Get("User-Agent", "")
		ua := user_agent.New(userAgentString)
		// 获取操作系统信息
		osInfo := ua.OSInfo()
		// 获取浏览器信息
		bName, bVersion := ua.Browser()
		sys.NewSysLogininforService().Add(ip, userName, constant.APP, bName, bVersion, osInfo.Name, osInfo.Version, token, err)
	}()

	var args pojo.AppLoginDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	err = args.Validator()
	if err != nil {
		return myerr.ERR_LOGIN_ARGS
	}
	userName = args.UserName

	// 获取客户端真实 IP 地址
	ip = ipaddr.New().GetIP(c)

	userId, token, err := appLoginService.Login(&args, ip)
	if err != nil {
		return err
	}
	if token == "" {
		return myerr.ERR_SYS_OPER
	}
	return resp.Resp(c, fiber.Map{
		"userId": userId,
		"token":  token,
	})
}

// GetInfo 获取个人信息
func (m *AppApiController) GetInfo(c *fiber.Ctx) error {
	user := resp.GetUser(c)
	vUser, err := appLoginService.GetInfo(user.Uid)
	if err != nil {
		return err
	}
	conf := config.Config.File
	vUser.Avatar = conf.BaseUrl + vUser.Avatar
	return resp.Resp(c, fiber.Map{
		"user": vUser,
	})
}

// LoginOut 退出登陆
func (m *AppApiController) LoginOut(c *fiber.Ctx) error {
	token := c.Params("tk")
	err := appLoginService.LoginOut(token)
	if err != nil {
		return err
	}
	return resp.Ok(c)
}

// Register 注册用户
func (m *AppApiController) Register(c *fiber.Ctx) error {
	var args entity.UserDto
	if err := c.BodyParser(&args); err != nil {
		return myerr.ERR_SYS_ARGS
	}
	_, err := appLoginService.Register(&args)
	if err != nil {
		return err
	}
	return resp.Ok(c)
}

// CaptchaImage 获取图片验证码
func (m *AppApiController) CaptchaImage(c *fiber.Ctx) error {
	captchaEnabled := config.Config.Login.CaptchaEnable
	if !captchaEnabled {
		return resp.Resp(c, fiber.Map{
			"captchaEnabled": captchaEnabled,
		})
	}
	id, b64s, _, err := appLoginService.CaptchaImage()
	if err != nil {
		return err
	}
	return resp.Resp(c, fiber.Map{
		"captchaEnabled": captchaEnabled,
		"uuid":           id,
		"img":            b64s,
	})
}

func (m *AppApiController) CaptchaVerify(c *fiber.Ctx) error {
	id := c.Query("id")
	code := c.Query("code")
	ok := captchaUtils.CaptchaVerify(id, code)
	if !ok {
		return myerr.ERR_LOGIN_VERIFY
	}
	return resp.Ok(c)
}

// GetEmailCode 获取邮箱验证码
func (m *AppApiController) GetEmailCode(c *fiber.Ctx) error {
	email := c.Query("email")
	err := emailUtils.SendCode(email, "验证码", "获取验证码")
	if err != nil {
		return err
	}
	return resp.Ok(c)
}

func (m *AppApiController) EmailCodeVerify(c *fiber.Ctx) error {
	email := c.Query("email")
	code := c.Query("code")
	ok := emailUtils.Verify(email, code)
	if !ok {
		return myerr.ERR_LOGIN_VERIFY
	}
	return resp.Ok(c)
}
